﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using starLiGHT.Physic.TwoD;
using TestBed;
#endregion

#region LICENSE

/*
    * This file is part of starLiGHT.Collision.
    * Copyright (c) 2007-2010 Roland Rosenkranz http://www.starLiGHT-Engine.de

    * This software is provided 'as-is', without any express or implied
    * warranty.  In no event will the authors be held liable for any damages
    * arising from the use of this software.
    * Permission is granted to anyone to use this software for any purpose,
    * including commercial applications, and to alter it and redistribute it
    * freely, subject to the following restrictions:
    * 1. The origin of this software must not be misrepresented; you must not
    * claim that you wrote the original software. If you use this software
    * in a product, an acknowledgment in the product documentation would be
    * appreciated but is not required.
    * 2. Altered source versions must be plainly marked as such, and must not be
    * misrepresented as being the original software.
    * 3. This notice may not be removed or altered from any source distribution.
    
    * ADDITIONAL (commercial) LICENSES for starLiGHT.Collision are available on request.
*/

#endregion

namespace starLiGHT.Sandbox.Physic2D
{
    public static class TestFactory
    {
        static Dictionary<String, int> nameToTestId;
        static int numTests;
        static int actTest;
        static String singleTest = String.Empty;

        static TestFactory()
        {
            nameToTestId = new Dictionary<String, int>();

            int index = 0;
            nameToTestId.Add("ApplyForce", index++);
            nameToTestId.Add("BodyTypes", index++);
            nameToTestId.Add("Breakable", index++);
            nameToTestId.Add("Bridge", index++);
            nameToTestId.Add("BulletTest", index++);
            nameToTestId.Add("Cantilever", index++);
            nameToTestId.Add("Car", index++);
            nameToTestId.Add("Chain", index++);
            nameToTestId.Add("CharacterCollision", index++);
            nameToTestId.Add("CollisionFiltering", index++);
            nameToTestId.Add("CollisionProcessing", index++);
            nameToTestId.Add("CompoundShapes", index++);
            nameToTestId.Add("Confined", index++);
            nameToTestId.Add("ContinuousTest", index++);
            nameToTestId.Add("DistanceTest", index++);
            nameToTestId.Add("Dominos", index++);
            nameToTestId.Add("DynamicTreeTest", index++);
            nameToTestId.Add("EdgeShapes", index++);
            nameToTestId.Add("EdgeTest", index++);
            nameToTestId.Add("Gears", index++);
            nameToTestId.Add("LineJoint", index++);
            nameToTestId.Add("OneSidedPlatform", index++);
            nameToTestId.Add("Pinball", index++);
            nameToTestId.Add("PolyCollision", index++);
            nameToTestId.Add("PolyShapes", index++);
            nameToTestId.Add("Prismatic", index++);
            nameToTestId.Add("Pulleys", index++);
            nameToTestId.Add("Pyramid", index++);
            nameToTestId.Add("RayCast", index++);
            nameToTestId.Add("Revolute", index++);
            nameToTestId.Add("RopeTest", index++);
            nameToTestId.Add("RopeJoint", index++);
            nameToTestId.Add("SensorTest", index++);
            nameToTestId.Add("ShapeEditing", index++);
            nameToTestId.Add("SliderCrank", index++);
            nameToTestId.Add("SphereStack", index++);
            nameToTestId.Add("Tiles", index++);
            nameToTestId.Add("TheoJansen", index++);
            nameToTestId.Add("TimeOfImpact", index++);
            nameToTestId.Add("VaryingFriction", index++);
            nameToTestId.Add("VaryingRestitution", index++);
            nameToTestId.Add("VerticalStack", index++);
            nameToTestId.Add("Web", index++);
            numTests = index;
        }

        public static Boolean ContainsTest(String testName)
        {
            foreach (String testKey in nameToTestId.Keys)
            {
                if (testName.Equals(testKey, StringComparison.CurrentCultureIgnoreCase))
                    return true;
            }

            return false;
        }

        public static String SingleTest
        {
            get { return singleTest; }
            set { singleTest = value; }
        }

        public static Test getTestByName(Microsoft.Xna.Framework.Game game, String name)
        {
            if (String.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
            if (game == null) throw new ArgumentNullException("game");

            if (nameToTestId.ContainsKey(name))
            {
                int testId = nameToTestId[name];
                return getTestById(game, testId);
            }

            throw new ArgumentException("unknown test name: " + name);
        }

        public static Test getTestById(Microsoft.Xna.Framework.Game game, int id)
        {
            if (id < 0 || id > numTests) throw new ArgumentOutOfRangeException("id");
            if (game == null) throw new ArgumentNullException("game");

            switch (id)
            {
                case 0: return new ApplyForce(game);
                case 1: return new BodyTypes(game);
                case 2: return new Breakable(game);
                case 3: return new Bridge(game);
                case 4: return new BulletTest(game);
                case 5: return new Cantilever(game);
                case 6: return new Car(game);
                case 7: return new Chain(game);
                case 8: return new CharacterCollision(game);
                case 9: return new CollisionFiltering(game);
                case 10: return new CollisionProcessing(game);
                case 11: return new CompoundShapes(game);
                case 12: return new Confined(game);
                case 13: return new ContinuousTest(game);
                case 14: return new DistanceTest(game);
                case 15: return new Dominos(game);
                case 16: return new DynamicTreeTest(game);
                case 17: return new EdgeShapes(game);
                case 18: return new EdgeTest(game);
                case 19: return new Gears(game);
                case 20: return new LineJoint(game);
                case 21: return new OneSidedPlatform(game);
                case 22: return new PinballTest(game);
                case 23: return new PolyCollision(game);
                case 24: return new PolyShapes(game);
                case 25: return new Prismatic(game);
                case 26: return new Pulleys(game);
                case 27: return new Pyramid(game);
                case 28: return new RayCast(game);
                case 29: return new Revolute(game);
                case 30: return new RopeTest(game);
                case 31: return new RopeJoint(game);
                case 32: return new SensorTest(game);
                case 33: return new ShapeEditing(game);
                case 34: return new SliderCrank(game);
                case 35: return new SphereStack(game);
                case 36: return new Tiles(game);
                case 37: return new TheoJansen(game);
                case 38: return new TimeOfImpact(game);
                case 39: return new VaryingFriction(game);
                case 40: return new VaryingRestitution(game);
                case 41: return new VerticalStack(game);
                case 42: return new Web(game);
                default: throw new ArgumentException("unknown test id: " + id.ToString());
            }
        }

        public static Test getActTest(Microsoft.Xna.Framework.Game game)
        {
            if (game == null) throw new ArgumentNullException("game");

            if (String.IsNullOrEmpty(singleTest))
                return getTestById(game, actTest);
            else
                return getTestByName(game, singleTest);
        }

        public static Test getNextTest(Microsoft.Xna.Framework.Game game)
        {
            if (game == null) throw new ArgumentNullException("game");

            if (String.IsNullOrEmpty(singleTest))
            {
                if (++actTest >= numTests) actTest = 0;

                return getTestById(game, actTest);
            }
            else
            {
                return getTestByName(game, singleTest);
            }
        }

        public static Test getPreviousTest(Microsoft.Xna.Framework.Game game)
        {
            if (game == null) throw new ArgumentNullException("game");

            if (String.IsNullOrEmpty(singleTest))
            {
                if (actTest-- <= 0) actTest = numTests - 1;

                return getTestById(game, actTest);
            }
            else
            {
                return getTestByName(game, singleTest);
            }
        }
    }
}
